import {_decorator, Button, Component, instantiate, Label, Layout, Prefab, Node, director} from "cc";
import {configsHelper} from "db://assets/script/configs-helper";
import {userInfo} from "db://assets/script/user-info";
import {PropItem} from "../props/prop-item";
import Long from "long";
import {PropDesc} from "db://assets/script/game/mainui/props/prop-desc";
import {utils} from "db://assets/script/utils/utils";
import {lobby} from "db://assets/script/lobby";
import {GameEvent} from "db://assets/script/game-event";
import {NormalBuildingStatus} from "db://assets/script/game/constants/normal-building-status";
import {CityBuildingCancelEdit} from "db://assets/script/common/events/city-events/city-building-cancel-edit";
import {NormalBuilding} from "db://assets/script/game/city/normal-building";
import {MixingMix} from "db://assets/script/common/events/mix-events/mixing-mix";

const {ccclass, property} = _decorator

@ccclass('ProducePlane')
export class ProducePlane extends Component {

    @property(Layout)
    outputPropBox!: Layout

    @property(Layout)
    requiredPropBox!: Layout

    @property(Button)
    produceUpBtn!: Button

    @property(Button)
    produceDownBtn!: Button

    @property(Label)
    produceNumLabel!: Label

    @property(Button)
    beginProduceBtn!: Button

    @property(Label)
    totalCostLabel!: Label

    @property(Prefab)
    propItemPref!: Prefab

    @property(Prefab)
    tipsPrefab!: Prefab;

    @property(Button)
    upgradeBtn!: Button

    @property(Label)
    title!: Label

    private _propItems: Map<number, PropItem> = new Map()
    private _propBaseNum: Map<number, number> = new Map()
    private _maxProduceNum: number = 1
    private _currentProduceNum: number = 0
    private _building!: NormalBuilding


    start() {
        this.produceUpBtn.node.on(Button.EventType.CLICK, this.produceUp, this)
        this.produceDownBtn.node.on(Button.EventType.CLICK, this.produceDown, this)
        this.beginProduceBtn.node.on(Button.EventType.CLICK, this.produceBegin, this)
    }

    init(building: NormalBuilding) {
        if (!configsHelper.checkResourceBuilding(building.buildingId, building.buildingItem!.level)) {
            this.node.destroy()
            return
        }
        this._building = building
        const bac = configsHelper.loadBuildingMixingFormulaConfigs(building.buildingItem!.buildingId, building.buildingItem!.level)
        if (!bac) {
            this.node.destroy()
            return
        }
        this.upgradeBtn.node.on(Button.EventType.CLICK, building.upgrade, building)
        const aac = configsHelper.loadBuildingAssetConfig(building.buildingId)
        if (aac) this.title.string = aac.name
        let maxProduceNum = Number.MAX_SAFE_INTEGER
        for (let asset of bac.showInput) {
            const current = userInfo.assetInfo.assets[asset.propId.toNumber()]
            if (!current) {
                maxProduceNum = 0
                break
            }
            const require = asset.num
            const pm = Math.floor(current.div(require).toNumber())
            if (maxProduceNum > pm) maxProduceNum = pm
        }
        this._maxProduceNum = maxProduceNum == Number.MAX_SAFE_INTEGER ? 0 : maxProduceNum
        this._currentProduceNum = this._maxProduceNum
        for (let asset of bac.showInput) {
            const pi = this._newPropItem(asset.propId.toNumber(), asset.num.mul(Math.max(this._currentProduceNum, 1)))
            this.requiredPropBox.node.addChild(pi)
        }
        for (let asset of bac.successShowOutput) {
            const pi = this._newPropItem(asset.propId.toNumber(), asset.num.mul(Math.max(this._currentProduceNum, 1)))
            this.outputPropBox.node.addChild(pi)
        }
        if (this._currentProduceNum > 0) {
            this.totalCostLabel.string = '耗时: ' + utils.timeDurationFormat(this._currentProduceNum * bac.costMs.toNumber())
        } else {
            this.totalCostLabel.string = '耗时: --秒'
        }
        this.produceNumLabel.string = this._currentProduceNum.toString()
    }

    produceUp() {
        if (this._currentProduceNum >= this._maxProduceNum) {
            lobby.instance.showToast('材料不足')
            return
        }
        this._currentProduceNum++
        this.produceNumLabel.string = this._currentProduceNum.toString()
        this.changeProduceNum()
    }

    produceDown() {
        if (this._currentProduceNum <= 0) return
        this._currentProduceNum--
        this.produceNumLabel.string = this._currentProduceNum.toString()
        this.changeProduceNum()
    }

    produceBegin() {
        if (this._currentProduceNum > 0) {
            const bac = configsHelper.loadBuildingMixingFormulaConfigs(this._building.buildingId, this._building.buildingItem!.level)
            if (bac) {
                const costAssets: { [key: number]: Long } = {}
                for (let asset of bac.input) {
                    costAssets[asset.propId.toNumber()] = asset.num.mul(this._currentProduceNum).mul(-1)
                }
                director.emit(GameEvent.mixingMix, new MixingMix('pipe_tag:building:1:' + this._building.buildingId.toString(), this._building.buildingItem!.buildingUniqueId, this._currentProduceNum, costAssets))
                this._building.changeStatus(NormalBuildingStatus.normal)
                director.emit(GameEvent.cityBuildingCancelEdit, new CityBuildingCancelEdit(this._building, false))
                this.node.destroy()
            }
        }
    }

    private changeProduceNum() {
        this._propItems.forEach((prop) => {
            prop.changeNum(this._propBaseNum.get(prop.assetId)! * Math.max(this._currentProduceNum, 1))
        })
        const bac = configsHelper.loadBuildingMixingFormulaConfigs(this._building.buildingId, this._building.buildingItem!.level)
        if (bac && this._currentProduceNum > 0) {
            this.totalCostLabel.string = '耗时: ' + utils.timeDurationFormat(this._currentProduceNum * bac.costMs.toNumber())
        } else {
            this.totalCostLabel.string = '耗时: --秒'
        }

    }


    private _newPropItem(assetId: number, num: Long) {
        const pi = instantiate(this.propItemPref)
        const propItem = pi.getComponent(PropItem)!
        propItem.init(assetId, num.toNumber())
        propItem.propIcon.node.on(Node.EventType.TOUCH_END, () => {
            this.showAssetTips(pi, assetId)
        })
        this._propItems.set(assetId, propItem)
        this._propBaseNum.set(assetId, num.toNumber())
        return pi
    }

    showAssetTips(targetNode: Node, assetId: number) {
        const tn = instantiate(this.tipsPrefab)
        lobby.instance.gui.addChild(tn)
        const propDesc = tn.getComponent(PropDesc)!
        propDesc.init(targetNode, assetId)
    }
}